/**
 * 文件上传相关的自定义Hook
 * 
 * 提供文件上传、进度跟踪和错误处理功能
 */
import { useState, useCallback } from 'react';
import { uploadService, UploadResponse, UploadProgress } from '../services/uploadService';

interface UseUploadState {
  isUploading: boolean;
  progress: UploadProgress | null;
  error: string | null;
  uploadedFile: UploadResponse | null;
}

interface UseUploadOptions {
  autoCompress?: boolean;
  maxWidth?: number;
  maxHeight?: number;
  quality?: number;
  onSuccess?: (result: UploadResponse) => void;
  onError?: (error: string) => void;
}

/**
 * 文件上传Hook
 */
export const useUpload = (options: UseUploadOptions = {}) => {
  const {
    autoCompress = true,
    maxWidth = 1920,
    maxHeight = 1080,
    quality = 0.8,
    onSuccess,
    onError
  } = options;

  const [state, setState] = useState<UseUploadState>({
    isUploading: false,
    progress: null,
    error: null,
    uploadedFile: null
  });

  /**
   * 重置状态
   */
  const reset = useCallback(() => {
    setState({
      isUploading: false,
      progress: null,
      error: null,
      uploadedFile: null
    });
  }, []);

  /**
   * 上传文件
   */
  const uploadFile = useCallback(async (file: File) => {
    try {
      setState(prev => ({
        ...prev,
        isUploading: true,
        error: null,
        progress: null
      }));

      let fileToUpload = file;

      // 如果是图片且启用了自动压缩
      if (autoCompress && file.type.startsWith('image/')) {
        try {
          fileToUpload = await uploadService.compressImage(
            file,
            maxWidth,
            maxHeight,
            quality
          );
        } catch (compressionError) {
          console.warn('图片压缩失败，使用原始文件:', compressionError);
          fileToUpload = file;
        }
      }

      // 上传文件
      const result = await uploadService.uploadImage(fileToUpload, (progress) => {
        setState(prev => ({
          ...prev,
          progress
        }));
      });

      setState(prev => ({
        ...prev,
        isUploading: false,
        uploadedFile: result,
        progress: { loaded: result.size, total: result.size, percentage: 100 }
      }));

      onSuccess?.(result);
      return result;

    } catch (error: any) {
      const errorMessage = error.message || '上传失败';
      
      setState(prev => ({
        ...prev,
        isUploading: false,
        error: errorMessage,
        progress: null
      }));

      onError?.(errorMessage);
      throw error;
    }
  }, [autoCompress, maxWidth, maxHeight, quality, onSuccess, onError]);

  /**
   * 上传多个文件
   */
  const uploadFiles = useCallback(async (files: File[]) => {
    const results: UploadResponse[] = [];
    const errors: string[] = [];

    for (let i = 0; i < files.length; i++) {
      try {
        const result = await uploadFile(files[i]);
        results.push(result);
      } catch (error: any) {
        errors.push(`文件 ${files[i].name}: ${error.message}`);
      }
    }

    return { results, errors };
  }, [uploadFile]);

  return {
    // 状态
    isUploading: state.isUploading,
    progress: state.progress,
    error: state.error,
    uploadedFile: state.uploadedFile,

    // 方法
    uploadFile,
    uploadFiles,
    reset
  };
};

/**
 * 图片上传Hook（专门用于图片）
 */
export const useImageUpload = (options: UseUploadOptions = {}) => {
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);

  const upload = useUpload({
    ...options,
    onSuccess: (result) => {
      // 清理预览URL
      if (previewUrl) {
        uploadService.revokePreviewUrl(previewUrl);
        setPreviewUrl(null);
      }
      options.onSuccess?.(result);
    }
  });

  /**
   * 选择并预览图片
   */
  const selectImage = useCallback((file: File) => {
    // 清理之前的预览URL
    if (previewUrl) {
      uploadService.revokePreviewUrl(previewUrl);
    }

    // 创建新的预览URL
    const newPreviewUrl = uploadService.createPreviewUrl(file);
    setPreviewUrl(newPreviewUrl);

    return newPreviewUrl;
  }, [previewUrl]);

  /**
   * 上传选中的图片
   */
  const uploadSelectedImage = useCallback(async (file: File) => {
    selectImage(file);
    return upload.uploadFile(file);
  }, [selectImage, upload.uploadFile]);

  /**
   * 清理预览
   */
  const clearPreview = useCallback(() => {
    if (previewUrl) {
      uploadService.revokePreviewUrl(previewUrl);
      setPreviewUrl(null);
    }
  }, [previewUrl]);

  return {
    ...upload,
    previewUrl,
    selectImage,
    uploadSelectedImage,
    clearPreview
  };
};

/**
 * 拖拽上传Hook
 */
export const useDragUpload = (options: UseUploadOptions = {}) => {
  const [isDragOver, setIsDragOver] = useState(false);
  const upload = useUpload(options);

  const handleDragEnter = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);

  const handleDrop = useCallback(async (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);

    const files = Array.from(e.dataTransfer.files);
    if (files.length > 0) {
      if (files.length === 1) {
        await upload.uploadFile(files[0]);
      } else {
        await upload.uploadFiles(files);
      }
    }
  }, [upload]);

  return {
    ...upload,
    isDragOver,
    dragHandlers: {
      onDragEnter: handleDragEnter,
      onDragLeave: handleDragLeave,
      onDragOver: handleDragOver,
      onDrop: handleDrop
    }
  };
};
